import React, { Component } from 'react';

import * as THREE from 'three';

import initRender from './initRender.js';

import pieMesh from './pieMesh.js';

import styles from './Pie3D.less';

export default class Pie3D extends Component {

    constructor(props) {
        super(props);
    }
    // 设置 props 默认值
    static defaultProps = {
        className: '',
        data: [
            {
                name: '红色文字\n换行', // \n 换行
                labelColor: '#ff0000', // null=取饼颜色
                fontSize: 40, // 默认12
                value: 0.3,
                showLine: true,
                showLabel: true,
                height: 0.1,           // 默认高度
                cursorHeight: 0.2,      // 鼠标移入时的高度
                lineSegment1: 1, // 线段1的长度
                lineSegment2: 1 // 线段2的长度
            }
        ],
        color: ['#d69f9f', '#3c763d', '#31708f', '#66b3ff', '#7c82ff', '#a94442']
    }

    rootDom = null;

    tooltip = null;// 数据弹窗

    // 初始化 state
    state = {
    }

    peiGroup = new class peiGroup extends THREE.Group { }();

    // 设置饼模型
    setPie = (props) => {

        const { data, color, scale = 1, labelGap = 0 } = props;

        let tatol = 0;// 所有值的总和
        data.map(d => tatol += d.value); // 计算总和
        let accumulate = 0;  // 累积计数器
        let startAngle = 0;  // 当前起始角度

        this.peiGroup.scale.set(scale, scale, scale); // 缩放

        this.peiGroup.children = this.peiGroup.children.slice(0, data.length); // 删除多出来的 饼图 如果有
        data.map((d, i) => {

            startAngle = accumulate; // 累加上之前已遍历成员的角度
            accumulate += parseFloat((d.value / tatol * Math.PI * 2).toFixed(3)); // 累加本成员的角度

            if (this.peiGroup.children[i]) { // 有就赋值
                this.peiGroup.children[i].parame.startAngle = startAngle;
                this.peiGroup.children[i].parame.endAngle = accumulate;
                this.peiGroup.children[i].parame.height = d.height;
                Object.assign(this.peiGroup.children[i].color, { ...new THREE.Color(color[i % color.length]) });

                this.peiGroup.children[i].userData = {
                    ...d,
                    lineSegment1: d.lineSegment1 || 1,
                    lineSegment2: d.lineSegment2 || 1,
                    proportion: parseFloat((d.value / tatol).toFixed(3))
                };

                this.peiGroup.children[i].onClick = e => this.props.onClick(e.object.userData);

                this.peiGroup.children[i].totooltipDOM = this.tooltip;
                this.peiGroup.children[i].setTotooltip = this.props.tooltip;

                this.peiGroup.children[i].line.visible = d.showLine !== false; // 是否显示线
                this.peiGroup.children[i].text.visible = d.showLabel !== false;// 是否显示文字
                this.peiGroup.children[i].text.textColor = d.labelColor || color[i % color.length];// 字体颜色
                this.peiGroup.children[i].text.fontSize = d.fontSize || 20;// 字体大小

            } else { // 没有就创建

                let pei = pieMesh(accumulate, color[i % color.length], labelGap, i); // 传入起始角度  和起始颜色

                pei.parame.startAngle = startAngle;
                pei.parame.endAngle = accumulate;
                pei.parame.height = d.height;

                pei.userData = {
                    ...d,
                    lineSegment1: d.lineSegment1 || 1,
                    lineSegment2: d.lineSegment2 || 1,
                    proportion: parseFloat((d.value / tatol).toFixed(3))
                };

                pei.text.text = d.name;

                Object.assign(pei.color, { ...new THREE.Color(color[i % color.length]) });

                pei.onClick = e => this.props.onClick(e.object.userData);

                pei.line.visible = d.showLine !== false;// 是否显示线
                pei.text.visible = d.showLabel !== false;// 是否显示线

                pei.totooltipDOM = this.tooltip;
                pei.setTotooltip = this.props.tooltip;
                pei.text.textColor = d.labelColor || color[i % color.length];// 字体颜色
                pei.text.fontSize = d.fontSize || 40;// 字体大小

                this.peiGroup.add(pei);
            }

        });

    }

    componentDidMount() {

        !this.renderer && initRender.call(this);

        this.peiGroup.rotation.x = Math.PI / -2;

        this.scene.add(this.peiGroup);

        this.setPie(this.props);

        this.renderer.domElement.addEventListener('mouseleave', () => {
            this.tooltip.style.opacity = 0;
        }, false); // 鼠标离开停止拾取

        this.renderer.domElement.addEventListener('mousemove', (() => {
            let rect = {};
            let width = 0;
            let height = 0;

            return e => {
                rect = this.tooltip.getBoundingClientRect(); // 获取div 的尺寸

                width = Math.ceil(rect.width);
                height = Math.ceil(rect.height);

                this.tooltip.style.left = e.offsetX - width - 10 + 'px';
                this.tooltip.style.top = e.offsetY - height - 10 + 'px';

            };

        })(), false);

    }

    // 移除时
    componentWillUnmount() {
        this.renderer.forceContextLoss(); // gpu 内存占用回收
    }

    UNSAFE_componentWillReceiveProps(nextProps) {// 16版react
        this.setPie(nextProps);
    }

    render() {
        const { className } = this.props;
        return (
            <div className={className} ref={dom => this.rootDom = dom} style={{ position: 'relative' }} >

                <div className={styles.tooltip} ref={dom => this.tooltip = dom} >123</div>

            </div>
        );
    }
}